package com.zhiche.lisa.bms.service.invoice.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.dao.mapper.invoice.InvoiceRegMapper;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceApply;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceReg;
import com.zhiche.lisa.bms.service.invoice.InvoiceApplyService;
import com.zhiche.lisa.bms.service.invoice.InvoiceRegService;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 发票登记 服务实现类
 * </p>
 *
 * @author hongbo
 * @since 2018-09-27
 */
@Service
public class InvoiceRegServiceImpl extends ServiceImpl<InvoiceRegMapper, InvoiceReg> implements InvoiceRegService {
    private static final Logger LOGGER = LoggerFactory.getLogger(InvoiceRegService.class);

    @Autowired
    private InvoiceApplyService invoiceApplyService;

    /**
     * 获取待付金额为空发票
     *
     * @return
     */
    @Override
    public Page<InvoiceReg> queryInvoiceRegOfNotLackSum(Page<InvoiceReg> page) {
        EntityWrapper<InvoiceReg> ew = new EntityWrapper<>();
        ew.isNull("invoice_lack_sum").or().ne("invoice_lack_sum", BigDecimal.ZERO);
        page.setRecords(baseMapper.selectPage(page, ew));
        return page;
    }

    /**
     * 更新发票已付金额
     *
     * @param invoiceRegList
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateInvoiceReSum(List<InvoiceReg> invoiceRegList) {
        LOGGER.info("InvoiceRegServiceImpl.updateInvoiceReSum param: {}", invoiceRegList);
        if (!CollectionUtils.isEmpty(invoiceRegList)) {
            List<InvoiceReg> updateRegList = Lists.newArrayList();
            invoiceRegList.forEach(invoice -> {
                InvoiceReg updateReg = new InvoiceReg();
                updateReg.setId(invoice.getId());
                updateReg.setInvoiceReSum(invoice.getInvoiceReSum());
                if (invoice.getInvoiceSum() != null && invoice.getInvoiceReSum() != null) {
                    updateReg.setInvoiceLackSum(invoice.getInvoiceSum().subtract(invoice.getInvoiceReSum()).setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                updateRegList.add(updateReg);
            });
            this.updateBatchById(updateRegList);
        }
    }

    /**
     * 无token查询
     *
     * @param headId
     * @return
     */
    @Override
    public List<InvoiceReg> selectInvoiceRegByHeadIdNoTenant(Long headId) {
        if (Objects.nonNull(headId)) {
            EntityWrapper<InvoiceReg> ew = new EntityWrapper<>();
            ew.eq("head_id", headId);
            return baseMapper.selectInvoiceRegNoTenant(ew);
        }
        return null;
    }

    /**
     * 删除
     *
     * @param headId
     */
    @Override
    public void deleteBatchByHeadId(Long headId) {
        if (Objects.nonNull(headId)) {
            EntityWrapper<InvoiceReg> ew = new EntityWrapper<>();
            ew.eq("head_id", headId);
            this.delete(ew);
        }
    }

    /**
     * 获取发票登记明细
     *
     * @param headerId
     * @return
     */
    @Override
    public List<InvoiceReg> selectInvoiceRegByHeaderId(Long headerId) {
        EntityWrapper<InvoiceReg> invoiceRegEntityWrapper = new EntityWrapper<>();
        invoiceRegEntityWrapper.eq("head_id", headerId);
        return baseMapper.selectList(invoiceRegEntityWrapper);
    }

    /**
     * 新增发票登记信息
     *
     * @param invoiceReg
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdateInvoiceReg(InvoiceReg invoiceReg) {
        if (Objects.isNull(invoiceReg)) throw new BaseException("无新增数据");
        if (Objects.isNull(invoiceReg.getId())) {
            if (Objects.isNull(invoiceReg.getInvoiceSum())) throw new BaseException("该发票无金额");
            if (Objects.isNull(invoiceReg.getInvoiceLackSum())) {
                invoiceReg.setInvoiceLackSum(invoiceReg.getInvoiceSum());
            }
            if (Objects.isNull(invoiceReg.getInvoiceReSum())) {
                invoiceReg.setInvoiceReSum(invoiceReg.getInvoiceSum().subtract(invoiceReg.getInvoiceLackSum()));
            }
            // invoiceReg.setTenantId(Long.valueOf(AccountUtil.getAccountInfoFromSecurityContext().getTenantId()));
            this.updateTenantId(invoiceReg);
            baseMapper.insert(invoiceReg);
        } else {
            this.updateById(invoiceReg);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void insertOrUpdateInvoiceRegList(List<InvoiceReg> invoiceRegs, Long headId) {
        if (!CollectionUtils.isEmpty(invoiceRegs)) {
            // 先判断删除
            deleteInvoiceRegByIdList(headId, invoiceRegs);
            List<InvoiceReg> addInvoiceRegs = new ArrayList<>();
            List<InvoiceReg> updateInvoiceRegs = new ArrayList<>();
            invoiceRegs.forEach(invoiceReg -> {
                if (Objects.isNull(invoiceReg.getId())) {
                    if (Objects.isNull(invoiceReg.getInvoiceSum())) throw new BaseException("发票无金额");
                    if (Objects.isNull(invoiceReg.getInvoiceLackSum())) {
                        invoiceReg.setInvoiceLackSum(invoiceReg.getInvoiceSum());
                    }
                    if (Objects.isNull(invoiceReg.getInvoiceReSum())) {
                        invoiceReg.setInvoiceReSum(invoiceReg.getInvoiceSum().subtract(invoiceReg.getInvoiceLackSum()));
                    }
                    // invoiceReg.setTenantId(Long.valueOf(AccountUtil.getAccountInfoFromSecurityContext().getTenantId()));
                    this.updateTenantId(invoiceReg);
                    addInvoiceRegs.add(invoiceReg);
                } else {
                    updateInvoiceRegs.add(invoiceReg);
                }
            });
            if (!CollectionUtils.isEmpty(addInvoiceRegs)) {
                this.insertBatch(addInvoiceRegs);
            }
            if (!CollectionUtils.isEmpty(updateInvoiceRegs)) {
                this.updateBatchById(updateInvoiceRegs);
            }
        } else {
            if (headId != null) {
                EntityWrapper<InvoiceReg> ew = new EntityWrapper<>();
                ew.eq("head_id", headId);
                this.delete(ew);
            }
        }
    }

    /**
     * 获取原有的id
     *
     * @param headId
     * @return
     */
    private void deleteInvoiceRegByIdList(Long headId, List<InvoiceReg> invoiceRegList) {
        List<Long> updateIdList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(invoiceRegList)) {
            invoiceRegList.stream()
                    .filter(reg -> reg.getId() != null)
                    .forEach(reg -> {
                        updateIdList.add(reg.getId());
                    });
        }
        EntityWrapper<InvoiceReg> ew = new EntityWrapper<>();
        ew.eq("head_id", headId);
        ew.setSqlSelect("id");
        List<Object> objectList = this.selectObjs(ew);
        if (!CollectionUtils.isEmpty(objectList)) {
            List<Long> idList = Lists.newArrayList();
            objectList.forEach(obj -> {
                idList.add(Long.parseLong(obj.toString()));
            });
            List<Long> deleteIdList = Lists.newArrayList();
            if (!CollectionUtils.isEmpty(updateIdList)) {
                idList.forEach(id -> {
                    if (!updateIdList.contains(id)) {
                        deleteIdList.add(id);
                    }
                });
            } else {
                deleteIdList.addAll(idList);
            }
            if (!CollectionUtils.isEmpty(deleteIdList)) {
                this.deleteBatchIds(deleteIdList);
            }
        }
    }

    /**
     * 批量新增发票登记信息
     *
     * @param invoiceRegs
     */
    @Override
    public void insertInvoiceRegList(List<InvoiceReg> invoiceRegs, Long headerId) {
        String tenantId = AccountUtil.getAccountInfoFromSecurityContext().getTenantId();
        for (InvoiceReg invoiceReg :
                invoiceRegs) {
            invoiceReg.setHeadId(headerId);
            if (Objects.isNull(invoiceReg.getInvoiceSum())) throw new BaseException("该发票无金额");
            if (Objects.isNull(invoiceReg.getInvoiceLackSum())) {
                invoiceReg.setInvoiceLackSum(invoiceReg.getInvoiceSum());
            }
            if (Objects.isNull(invoiceReg.getInvoiceReSum())) {
                invoiceReg.setInvoiceReSum(invoiceReg.getInvoiceSum().subtract(invoiceReg.getInvoiceLackSum()));
            }
            // invoiceReg.setTenantId(tenantId == null ? null : Long.valueOf(tenantId));
            this.updateTenantId(invoiceReg);
        }
        this.insertBatch(invoiceRegs);
    }

    private void updateTenantId(InvoiceReg invoiceReg) {
        if (Objects.nonNull(invoiceReg) && Objects.nonNull(invoiceReg.getHeadId())) {
            InvoiceApply invoiceApply = invoiceApplyService.selectById(invoiceReg.getHeadId());
            if (Objects.nonNull(invoiceApply)) {
                invoiceReg.setTenantId(invoiceApply.getTenantId());
            }
        }

    }
}
